<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<body>
<script>
async_test(t => {
  // Test that ResizeObserver and its callback function do not cause any crash.
  // This test is considered as successful as long as the test doesn't crash.
  // See also https://crbug.com/792604 and https://crbug.com/809784 .

  let target_element = document.createElement('div');
  document.body.appendChild(target_element);

  // Run a bunch of ResizeObservers to expect high probability to cause a crash.
  const num_of_observers = 100;
  resize_observers = new Array(num_of_observers);
  for (let i = 0; i < num_of_observers; ++i) {
    resize_observers[i] = new ResizeObserver(entries => {
      for (let i = 0; i < num_of_observers; ++i) {
        if (resize_observers[i] === null) continue;
        // An Element retains the callback functions that are observing the
        // change on size of the Element. Make the Element not retain the
        // callback functions.
        resize_observers[i].unobserve(target_element);
        // Make the test itself not retain the callback functions.
        resize_observers[i] = null;
      }

      // Try to collect the callback functions.
      gc();

      on_observed();
    });

    resize_observers[i].observe(target_element);
  }

  let observation_count = 0;
  // Wait for the test to finish resize observations for a while.
  let test_done_timer = null;
  const test_done_timer_delay = 100;
  const on_observed = () => {
    ++observation_count;

    if (test_done_timer !== null)
      return;

    test_done_timer = setTimeout(() => {
      // https://wicg.github.io/ResizeObserver/#broadcast-resize-notifications-h
      // 3.3.4. Broadcast active observations is a bit ambiguous about whether
      // |unobserve| in the callback functions takes effect immediately or
      // delayed. Assuming that it must take effect immediately, the expected
      // number of observations is 1.
      assert_equals(observation_count, 1);

      target_element.remove();
      t.done();
    }, test_done_timer_delay);
  };

  target_element.style.width = "42px";
}, "Tries to break wrapper-tracing and to make it crash.");
</script>
</body>
